package com.gxar.quick.ar.server.base.common.utils;

import com.gxar.common.utils.SnowFlakeUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.ByteBuffer;
import java.util.Base64;

public class ShortReversibleEncryptionExample {

    public static void main(String[] args) {
        try {
            long originalValue = Long.parseLong(SnowFlakeUtils.getInstance().nextId());

            // 生成密钥
            SecretKey secretKey = generateSecretKey();

            // 加密
            String encryptedValue = encrypt(originalValue, secretKey);

            // 解密
            long decryptedValue = decrypt(encryptedValue, secretKey);

            System.out.println("secretKey Value: " + secretKey.getFormat());
            System.out.println("Original Value: " + originalValue);
            System.out.println("Encrypted Value: " + encryptedValue);
            System.out.println("Decrypted Value: " + decryptedValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static SecretKey generateSecretKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
        return keyGenerator.generateKey();
    }

    private static String encrypt(long value, SecretKey secretKey) throws Exception {
        // 使用 DES 加密算法进行加密
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

        // 加密后的二进制数据
        byte[] encryptedBytes = cipher.doFinal(toBytes(value));

        // Base64 编码
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    private static long decrypt(String encryptedValue, SecretKey secretKey) throws Exception {
        // Base64 解码
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedValue);

        // 使用 DES 解密算法进行解密
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);

        // 解密后的二进制数据
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

        return fromBytes(decryptedBytes);
    }

    private static byte[] toBytes(long value) {
        byte[] result = new byte[8];
        for (int i = 7; i >= 0; i--) {
            result[i] = (byte) (value & 0xFF);
            value >>= 8;
        }
        return result;
    }

    private static long fromBytes(byte[] bytes) {
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        return buffer.getLong();
    }
}
